package managers.dateManager.endFrozen.endChange;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import junit.framework.TestCase;

import org.apache.log4j.Logger;
import org.tbjd.client.beans.Task;
import org.tbjd.client.constants.NotificationsConstants;
import org.tbjd.client.constants.TimeConstants;
import org.tbjd.client.exceptions.TaskManagerException;
import org.tbjd.client.managers.TaskManager;
import org.tbjd.client.states.StateEndFrozenSPEC;

import factories.TaskFactory;

/**
 * <p>
 * Test TaskManager's methods
 * </p>
 * <p>
 * <b>Case</b>
 * </p>
 * <p>
 * Task with EndDate frozen and no relationships (predecessors/successors)
 * </p>
 * <p>
 * <b>Action</b>
 * </p>
 * <p>
 * Change end of the task "task"
 * </p>
 * <p>
 * <b> Expected</b>
 * <ul>
 * <li>update BeginDate</li>
 * </ul>
 * </p>
 * 
 * @author Michael Martin
 * @author Antonio Carrozzini
 * @version 1.0
 */
public class EndFrozen_EndChange_UpdateSingleTask_Basic extends TestCase {

	private Task task = null;
	private Map<Integer, Object> map = null;
	private Logger log = Logger.getLogger("console");
	private DateFormat df = DateFormat.getInstance();
	private TaskManager dateManager = new TaskManager();
	private static final long ADDED_DAYS = 2;

	protected void setUp() throws Exception {
		df = new SimpleDateFormat("dd.MM.yyyy");

		task = (Task) TaskFactory.getInstance();
		task.setState(new StateEndFrozenSPEC(task.getState().getDurationModeState()));

		super.setUp();
	}

	public void testListNullity() {
		System.out.println("");
		log.debug(" === testListNullity");

		Date newEndDate = new Date(this.task.getEndDate().getTime() + (ADDED_DAYS * TimeConstants.DAY_IN_MILLIS));
		log.debug("new EndDate = " + df.format(newEndDate));

		this.map = new HashMap<Integer, Object>();
		this.map.put(NotificationsConstants.DATEMANAGER_ACTION_endDate, newEndDate);
		this.map.put(NotificationsConstants.DATEMANAGER_BEAN, this.task);
		this.map.put(NotificationsConstants.DATEMANAGER_SENDER, null);

		log.debug("call TaskManager...");
		try {
			assertNotNull("Updated bean list isn't null", dateManager.manageDates(map));

		} catch (TaskManagerException e) {
			fail(e.getMessage());

		}

	}

	public void testListSize() {
		System.out.println("");
		log.debug(" === testListSize");

		Date newEndDate = new Date(this.task.getEndDate().getTime() + (ADDED_DAYS * TimeConstants.DAY_IN_MILLIS));
		log.debug("new EndDate = " + df.format(newEndDate));

		this.map = new HashMap<Integer, Object>();
		this.map.put(NotificationsConstants.DATEMANAGER_ACTION_endDate, newEndDate);
		this.map.put(NotificationsConstants.DATEMANAGER_BEAN, this.task);

		log.debug("call dateManager...");
		List<Task> updatedBeans = null;
		try {
			updatedBeans = dateManager.manageDates(this.map);

		} catch (TaskManagerException e) {
			fail(e.getMessage());

		}
		assertEquals(1, updatedBeans.size());

	}

	public void testInstanceEquality() {
		System.out.println("");
		log.debug(" === testInstanceEquality");

		Date newEndDate = new Date(this.task.getEndDate().getTime() + (ADDED_DAYS * TimeConstants.DAY_IN_MILLIS));
		log.debug("new EndDate = " + df.format(newEndDate));

		this.map = new HashMap<Integer, Object>();
		this.map.put(NotificationsConstants.DATEMANAGER_ACTION_endDate, newEndDate);
		this.map.put(NotificationsConstants.DATEMANAGER_BEAN, this.task);

		log.debug("call dateManager...");
		List<Task> updatedBeans = null;
		try {
			updatedBeans = dateManager.manageDates(map);

		} catch (TaskManagerException e) {
			fail(e.getMessage());

		}

		assertEquals(task, updatedBeans.get(0));

	}

	public void testEfforts() {
		System.out.println("");
		log.debug(" === testEfforts");

		Date newEndDate = new Date(this.task.getEndDate().getTime() + (ADDED_DAYS * TimeConstants.DAY_IN_MILLIS));
		log.debug("new EndDate = " + df.format(newEndDate));

		this.map = new HashMap<Integer, Object>();
		this.map.put(NotificationsConstants.DATEMANAGER_ACTION_endDate, newEndDate);
		this.map.put(NotificationsConstants.DATEMANAGER_BEAN, this.task);

		log.debug("call dateManager...");
		List<Task> updatedBeans = null;
		try {
			updatedBeans = dateManager.manageDates(this.map);

		} catch (TaskManagerException e) {
			fail(e.getMessage());

		}

		log.debug("No Resources for this Task, thus Effort = Duration");
		assertEquals((float) updatedBeans.get(0).getDuration(), (float) updatedBeans.get(0).getEffort());

	}

	public void testDurations() {
		System.out.println("");
		log.debug(" === testDurations");

		float originalDuration = task.getDuration();
		Date newEndDate = new Date(this.task.getEndDate().getTime() + (ADDED_DAYS * TimeConstants.DAY_IN_MILLIS));
		log.debug("new EndDate = " + df.format(newEndDate));

		this.map = new HashMap<Integer, Object>();
		this.map.put(NotificationsConstants.DATEMANAGER_ACTION_endDate, newEndDate);
		this.map.put(NotificationsConstants.DATEMANAGER_BEAN, this.task);

		log.debug("call dateManager...");
		List<Task> updatedBeans = null;
		try {
			updatedBeans = dateManager.manageDates(this.map);

		} catch (TaskManagerException e) {
			fail(e.getMessage());

		}

		assertEquals(originalDuration, updatedBeans.get(0).getDuration());

	}

	public void testDates() {
		System.out.println("");
		log.debug(" === testDates");

		Date originalBeginDate = task.getBeginDate();
		Date originalEndDate = task.getEndDate();

		Date newEndDate = new Date(this.task.getEndDate().getTime() + (ADDED_DAYS * TimeConstants.DAY_IN_MILLIS));
		log.debug("new EndDate = " + df.format(newEndDate));

		this.map = new HashMap<Integer, Object>();
		this.map.put(NotificationsConstants.DATEMANAGER_ACTION_endDate, newEndDate);
		this.map.put(NotificationsConstants.DATEMANAGER_BEAN, this.task);

		log.debug("compute...");
		List<Task> updatedBeans = null;
		try {
			updatedBeans = dateManager.manageDates(this.map);

		} catch (TaskManagerException e) {
			fail(e.getMessage());

		}

		log.debug("original BeginDate = " + df.format(originalBeginDate) + " and new BeginDate = " + df.format(updatedBeans.get(0).getBeginDate()));
		log.debug("original EndDate = " + df.format(originalEndDate) + " and new EndDate = " + df.format(updatedBeans.get(0).getEndDate()));
		try {
			assertEquals(df.parseObject("3.6.2009"), updatedBeans.get(0).getBeginDate());
			assertEquals(df.parseObject("4.6.2009"), updatedBeans.get(0).getEndDate());

		} catch (ParseException e) {
			fail(e.getMessage());

		}

	}

}
